package com.seal.commons.generator.util;

import com.seal.commons.generator.config.StrategyConfig;
import com.seal.commons.generator.enums.JavaType;
import com.seal.commons.generator.vo.TableField;
import com.seal.commons.generator.vo.TableInfo;
import org.apache.commons.collections.CollectionUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 功能描述: <br/>
 *
 * @author yong.huang
 * @date: 2020-08-10 20:42<br/>
 * @since JDK 1.8
 */
public class ConvertUtils {

    public static final Pattern pattern = Pattern.compile("\\d+");
    private TableInfo tableInfo;

    private StrategyConfig strategyConfig;

    private ConvertUtils(){}

    public ConvertUtils(TableInfo tableInfo, StrategyConfig strategyConfig){
        this.tableInfo = tableInfo;
        this.strategyConfig = strategyConfig;
    }

    public void convert(){
        convertEntityName();
        convertField();
        convertBOName();
        convertDTOName();
        convertRepositoryName();
        convertServiceName();
        convertServiceImplName();
    }

    private void convertEntityName(){
        String tempName = this.tableInfo.getName();
        if(strategyConfig.isRemoveTablePrefix()){
            tempName = NamingStrategy.removePrefix(tempName, strategyConfig.getTablePrefix());
        }
        tempName = NamingStrategy.underlineToCamel(tempName);
        tableInfo.setEntityName(NamingStrategy.capitalFirst(tempName));
        if(StringUtils.isNotBlank(strategyConfig.getSuperEntityClass())){
            String supperEntityClass = strategyConfig.getSuperEntityClass();
          //  tableInfo.getImportPackages().add(supperEntityClass);
            tableInfo.setSuperClassName(supperEntityClass.substring(supperEntityClass.lastIndexOf(".")+1));
        }
    }

    private void convertField(){
        List<TableField> fields = tableInfo.getFields();
        Collections.sort(fields, new Comparator<TableField>() {
            @Override
            public int compare(TableField o1, TableField o2) {
                return o1.getIndex()-o2.getIndex();
            }
        });
        if(CollectionUtils.isNotEmpty(fields)){
            Iterator<TableField> iterable = fields.iterator();
            while (iterable.hasNext()){
                TableField tableField = iterable.next();
                if(!include(strategyConfig.getSuperEntityColumns(), tableField)){
                    covertField(tableField);
                }else{
                    iterable.remove();
                }
            }
        }
        covertField(tableInfo.getPkField());
    }

    private boolean include(String[] superEntityColumns, TableField field) {
        for(int i=0; i< superEntityColumns.length; i++){
            if(superEntityColumns[i].equals(field.getName())){
                return true;
            }
        }
        return false;
    }

    private void covertField(TableField field){
        field.setJavaType(JavaType.getJavaType(field.getType()));
        field.setSize(getFieldSize(field.getType()));
        this.tableInfo.addImportPackage(JavaType.getPackageImport(field.getJavaType()));
        field.setFieldName(NamingStrategy.underlineToCamel(field.getName()));
        String capitalName = NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(field.getName()));
        field.setGetMethod("get" + capitalName);
        field.setSetMethod("set" + capitalName);
    }

    private void convertRepositoryName() {
        tableInfo.setRepositoryName(tableInfo.getEntityName() + "Repository");
    }

    private void convertBOName(){
        tableInfo.setBoName(tableInfo.getEntityName() + "BO");
    }

    private void convertDTOName(){
        tableInfo.setDtoName(tableInfo.getEntityName() + "DTO");
    }
    private void convertServiceName(){
        tableInfo.setServiceName(tableInfo.getEntityName() + "Service");
    }

    private void convertServiceImplName(){
        tableInfo.setServiceImplName(tableInfo.getEntityName() + "ServiceImpl");
    }

    public Integer getFieldSize(String sqlType) {
        Matcher matcher = pattern.matcher(sqlType);
        while (matcher.find()) {
            return Integer.valueOf(matcher.group(0));
        }
        return null;
    }

}